#include "viml/builtin_list.h"
#include "viml/value.h"
#include "viml/vm.h"
#include <algorithm>
#include <stdexcept>
#include <cmath>

namespace viml {

// len(list) 函数实现
Value len_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("len() requires exactly 1 argument");
    }
    
    // 检查参数类型
    const auto& arg = args[0];
    if (arg.is_list()) {
        return Value::make_number(static_cast<int64_t>(arg.as_list().size()));
    } else if (arg.is_string()) {
        return Value::make_number(static_cast<int64_t>(arg.as_string().length()));
    } else if (arg.is_dict()) {
        return Value::make_number(static_cast<int64_t>(arg.as_dict().size()));
    } else {
        throw std::runtime_error("len() argument must be a list, string, or dict");
    }
}

// add(list, item) 函数实现
Value add_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 2) {
        throw std::runtime_error("add() requires exactly 2 arguments");
    }
    
    // 检查第一个参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to add() must be a list");
    }
    
    // 获取列表引用并添加元素（原地修改）
    Value& list_ref = const_cast<Value&>(args[0]);
    list_ref.as_list().push_back(args[1]);
    
    return list_ref;
}

// insert(list, item) / insert(list, idx, item) 函数实现
Value insert_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() < 2 || args.size() > 3) {
        throw std::runtime_error("insert() requires 2 or 3 arguments");
    }
    
    // 检查第一个参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to insert() must be a list");
    }
    
    Value& list_ref = const_cast<Value&>(args[0]);
    auto& mutable_list = list_ref.as_list();
    
    if (args.size() == 2) {
        // insert(list, item) - 在开头插入
        mutable_list.insert(mutable_list.begin(), args[1]);
    } else {
        // insert(list, idx, item) - 在指定位置插入
        int64_t idx = args[1].to_number();
        
        // 处理负索引
        if (idx < 0) {
            idx = static_cast<int64_t>(mutable_list.size()) + idx;
        }
        
        // 检查索引范围
        if (idx < 0 || static_cast<size_t>(idx) > mutable_list.size()) {
            throw std::runtime_error("Index out of range in insert()");
        }
        
        mutable_list.insert(mutable_list.begin() + idx, args[2]);
    }
    
    return list_ref;
}

// remove(list, idx) / remove(list, start, end) / remove(dict, key) 函数实现
Value remove_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() < 2 || args.size() > 3) {
        throw std::runtime_error("remove() requires 2 or 3 arguments");
    }
    
    // 检查第一个参数是否为列表或字典
    if (args[0].is_list()) {
        Value& list_ref = const_cast<Value&>(args[0]);
        auto& mutable_list = list_ref.as_list();
        
        if (args.size() == 2) {
            // remove(list, idx) - 移除单个元素
            int64_t idx = args[1].to_number();
            
            // 处理负索引
            if (idx < 0) {
                idx = static_cast<int64_t>(mutable_list.size()) + idx;
            }
            
            // 检查索引范围
            if (idx < 0 || static_cast<size_t>(idx) >= mutable_list.size()) {
                throw std::runtime_error("Index out of range in remove()");
            }
            
            Value removed_value = mutable_list[idx];
            mutable_list.erase(mutable_list.begin() + idx);
            
            return removed_value;
        } else {
            // remove(list, start, end) - 移除范围内的元素
            int64_t start_idx = args[1].to_number();
            int64_t end_idx = args[2].to_number();
            
            // 处理负索引
            if (start_idx < 0) {
                start_idx = static_cast<int64_t>(mutable_list.size()) + start_idx;
            }
            if (end_idx < 0) {
                end_idx = static_cast<int64_t>(mutable_list.size()) + end_idx;
            }
            
            // 检查索引范围
            if (start_idx < 0 || static_cast<size_t>(start_idx) >= mutable_list.size() ||
                end_idx < 0 || static_cast<size_t>(end_idx) >= mutable_list.size() ||
                start_idx > end_idx) {
                throw std::runtime_error("Index out of range in remove()");
            }
            
            // 创建要返回的列表
            Value result_list = Value::list();
            auto& result_elements = result_list.as_list();
            
            // 复制要移除的元素
            for (int64_t i = start_idx; i <= end_idx; ++i) {
                result_elements.push_back(mutable_list[i]);
            }
            
            // 从原列表中移除元素
            mutable_list.erase(mutable_list.begin() + start_idx, mutable_list.begin() + end_idx + 1);
            
            return result_list;
        }
    } else if (args[0].is_dict()) {
        // remove(dict, key) - 移除字典中的键值对
        if (args.size() != 2) {
            throw std::runtime_error("remove() for dict requires exactly 2 arguments");
        }
        
        // 检查第二个参数是否为字符串
        if (!args[1].is_string()) {
            throw std::runtime_error("Second argument to remove() for dict must be a string");
        }
        
        // 获取字典引用
        Value& dict_ref = const_cast<Value&>(args[0]);
        auto& mutable_dict = dict_ref.as_dict();
        
        // 获取键
        const std::string& key = args[1].as_string();
        
        // 查找键
        auto it = mutable_dict.find(key);
        if (it != mutable_dict.end()) {
            // 键存在，保存值并删除键值对
            Value removed_value = it->second;
            mutable_dict.erase(it);
            return removed_value;
        } else {
            // 键不存在，抛出异常
            throw std::runtime_error("Key not found in dict");
        }
    } else {
        throw std::runtime_error("First argument to remove() must be a list or dict");
    }
}

// index(list, value) / index(list, value, start) 函数实现
Value index_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() < 2 || args.size() > 3) {
        throw std::runtime_error("index() requires 2 or 3 arguments");
    }
    
    // 检查第一个参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to index() must be a list");
    }
    
    const auto& list = args[0].as_list();
    const Value& search_value = args[1];
    
    // 确定起始索引
    size_t start_idx = 0;
    if (args.size() == 3) {
        int64_t start = args[2].to_number();
        if (start < 0) {
            start = static_cast<int64_t>(list.size()) + start;
        }
        if (start < 0) {
            start = 0;
        }
        start_idx = static_cast<size_t>(start);
    }
    
    // 查找元素
    for (size_t i = start_idx; i < list.size(); ++i) {
        if (list[i] == search_value) {
            Value result = Value::make_number(static_cast<int64_t>(i));
            return result;
        }
    }
    
    // 未找到返回-1
    Value result = Value::make_number(-1);
    return result;
}

// count(list, value) 函数实现
Value count_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 2) {
        throw std::runtime_error("count() requires exactly 2 arguments");
    }
    
    // 检查第一个参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to count() must be a list");
    }
    
    const auto& list = args[0].as_list();
    const Value& search_value = args[1];
    
    // 计算出现次数
    int64_t count = 0;
    for (const auto& element : list) {
        if (element == search_value) {
            count++;
        }
    }
    
    return Value::make_number(count);
}

// reverse(list) 函数实现
Value reverse_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("reverse() requires exactly 1 argument");
    }
    
    // 检查参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to reverse() must be a list");
    }
    
    Value& list_ref = const_cast<Value&>(args[0]);
    auto& mutable_list = list_ref.as_list();
    
    // 反转列表
    std::reverse(mutable_list.begin(), mutable_list.end());
    
    return list_ref;
}

// sort(list) / sort(list, {cmp}) 函数实现
Value sort_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() < 1 || args.size() > 2) {
        throw std::runtime_error("sort() requires 1 or 2 arguments");
    }
    
    // 检查第一个参数是否为列表
    if (!args[0].is_list()) {
        throw std::runtime_error("First argument to sort() must be a list");
    }
    
    Value& list_ref = const_cast<Value&>(args[0]);
    auto& mutable_list = list_ref.as_list();
    
    if (args.size() == 1) {
        // 默认排序
        std::sort(mutable_list.begin(), mutable_list.end());
    } else {
        // 使用自定义比较函数排序（简化实现，仅支持默认排序）
        std::sort(mutable_list.begin(), mutable_list.end());
    }
    
    return list_ref;
}

// copy(list/dict) 函数实现
Value copy_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("copy() requires exactly 1 argument");
    }
    
    // 检查参数是否为列表或字典
    if (args[0].is_list()) {
        // 创建列表的浅拷贝
        const auto& original_list = args[0].as_list();
        Value new_list = Value::list();
        auto& new_elements = new_list.as_list();
        
        // 复制所有元素（浅拷贝）
        new_elements.insert(new_elements.end(), original_list.begin(), original_list.end());
        
        return new_list;
    } else if (args[0].is_dict()) {
        // 创建字典的浅拷贝
        const auto& original_dict = args[0].as_dict();
        Value new_dict = Value::dict();
        auto& new_entries = new_dict.as_dict();
        
        // 复制所有键值对（浅拷贝）
        for (const auto& pair : original_dict) {
            new_entries[pair.first] = pair.second;
        }
        
        return new_dict;
    } else {
        throw std::runtime_error("First argument to copy() must be a list or dict");
    }
}

// deepcopy(list/dict) 函数实现
Value deepcopy_builtin(const std::vector<Value>& args) {
    // 检查参数数量
    if (args.size() != 1) {
        throw std::runtime_error("deepcopy() requires exactly 1 argument");
    }
    
    // 检查参数是否为列表或字典
    if (args[0].is_list()) {
        // 创建列表的深拷贝
        const auto& original_list = args[0].as_list();
        Value new_list = Value::list();
        auto& new_elements = new_list.as_list();
        
        // 递归深拷贝所有元素
        for (const auto& element : original_list) {
            if (element.is_list()) {
                // 递归深拷贝列表
                std::vector<Value> arg_vec = {element};
                new_elements.push_back(deepcopy_builtin(arg_vec));
            } else if (element.is_dict()) {
                // 递归深拷贝字典
                std::vector<Value> arg_vec = {element};
                new_elements.push_back(deepcopy_builtin(arg_vec));
            } else {
                // 基本类型直接复制
                new_elements.push_back(element);
            }
        }
        
        return new_list;
    } else if (args[0].is_dict()) {
        // 创建字典的深拷贝
        const auto& original_dict = args[0].as_dict();
        Value new_dict = Value::dict();
        auto& new_entries = new_dict.as_dict();
        
        // 递归深拷贝所有键值对
        for (const auto& pair : original_dict) {
            const Value& value = pair.second;
            if (value.is_list()) {
                // 递归深拷贝列表
                std::vector<Value> arg_vec = {value};
                new_entries[pair.first] = deepcopy_builtin(arg_vec);
            } else if (value.is_dict()) {
                // 递归深拷贝字典
                std::vector<Value> arg_vec = {value};
                new_entries[pair.first] = deepcopy_builtin(arg_vec);
            } else {
                // 基本类型直接复制
                new_entries[pair.first] = value;
            }
        }
        
        return new_dict;
    } else {
        throw std::runtime_error("First argument to deepcopy() must be a list or dict");
    }
}

} // namespace viml